package Bank;


import java.util.InputMismatchException;

import java.util.Scanner;
import java.util.LinkedList;
public class Main {
    public static void main(String[] args) {
        BankSystem bankSystem=new BankSystem();
        bankSystem.mainMenu();
    }
}
abstract class Card {
    String account;
    String password;
    double balance;
    public String getAccount() {
        return account;
    }
    Card(String account){
        Scanner scanner=new Scanner(System.in);
		this.account=account;
        System.out.println("请输入密码");
		this.password=scanner.next();
        System.out.println("注册成功");
        this.balance= BankMenu.getDigit("请输入初始余额：");
    }
    boolean checkPassword(String trial){
        return trial.equals(this.password);
    }
    void ATM(){
        while (true)
        {
            String[] choices = {
                    "1.存款",
                    "2.取款",
                    "3.查询余额",
                    "0.登出账号"
            };
            switch (BankMenu.selectMenu(choices)) {
                case 1:
                    this.deposit(BankMenu.getDigit("请输入存入金额") );
                    break;
                case 2:
                    this.withdraw(BankMenu.getDigit("请输入取款金额"));
                    break;
                case 3:
                    this.show();
                    break;
                case 0:
                    return;
            }
        }
    }
    void show(){
        System.out.println("账号：\t"+this.account);
        System.out.println("余额：\t"+this.balance);
    }
    void deposit(double amount){
        this.balance+=amount;
    }
    abstract void withdraw(double amount);
    abstract void consume(double amount);
}
class DepositCard extends Card{
    DepositCard(String account) {
        super(account);
    }

	@Override
	void show() {
		super.show();
		System.out.println("类型：\t储值卡");
	}

	void withdraw(double amount){
        boolean res=amount<=this.balance;
        if(res) this.balance-=amount;
        else System.out.println("余额不足，无法提款");
	}
    void consume(double amount){
        boolean res=amount<=this.balance;
        if(res) this.balance-=amount;
        else System.out.println("余额不足，无法消费");
	}
}
class CreditCard extends Card{
    final int NEGATIVE_LIM=1000;
    CreditCard(String account) {super(account);}
    @Override
    void show() {
		super.show();
		System.out.println("类型：\t信用卡");
	}
    @Override
	void withdraw(double amount) {
        boolean res=
                amount<=(this.balance+this.NEGATIVE_LIM);
        if(res) {
            this.balance-=amount;
            if(this.balance<0) System.out.println("您已透支，请及时充值");
        }
        else System.out.println("您已达到透支额度，无法提款");
	}
    @Override
	void consume(double amount) {
        boolean res=
                amount<=(this.balance+this.NEGATIVE_LIM);
        if(res) {
            this.balance-=amount;
            if(this.balance<0) System.out.println("您已透支，请及时充值");
        }
        else System.out.println("您已达到透支额度，无法消费");
	}
}
class BankMenu {
    static Scanner scanner=new Scanner(System.in);
    static int selectMenu(String[] choices){
        int result;
        while (true){
            try {
                for(String choice:choices)
                    System.out.println(choice);
                result=scanner.nextInt();
                if(result>=0&&result<choices.length)
                    return result;
                else System.out.println("无此选项");
                System.out.println("选择失败");
                System.out.println("请再试一次");
            }
            catch (InputMismatchException inputMismatchException){
                System.out.println("无效数字");
            }
        }
    }
    static float getDigit(String prompt){
        float result;
        while (true){
            try {
                System.out.println(prompt);
                result=scanner.nextFloat();
                return result;
            }
            catch (InputMismatchException inputMismatchException){
                System.out.println("无效数字");
                System.out.println("请再试一次");
            }
        }
    }

}
class BankSystem{
    static LinkedList<Card> cardCollection=new LinkedList<>();
    public static Card findAccount(String name,
	boolean create){
        for(Card card:cardCollection){
            if(name.equals(card.getAccount()))
                return card;
        }
		if(!create)
        	System.out.println("账号或密码错误");
        return null;
    }
    void mainMenu(){
        String[] choices={"1.开户","2.ATM(存、取款、查询账户)","3.消费pos机","0.退出"};
        Scanner scanner=new Scanner(System.in);
        Card thisCard=null;
		String account;
		while (true)
            switch (BankMenu.selectMenu(choices)){
                case 1:
					thisCard=initAccount();
					if(thisCard!=null)
                    	cardCollection.add(thisCard);
					else System.out.println("注册失败");
                    break;
                case 2:
                    while (thisCard==null){
                        System.out.println("请输入账号和密码(输入0退出)");
						account=scanner.next();
						if(account.equals("0")) {
							System.out.println("欢迎下次使用！");
							break;
						}
                        thisCard=findAccount(account,false);
                        if(thisCard==null) System.out.println("账号未注册，请重试");
                        else if (thisCard.checkPassword(scanner.next()))
                            break;
                        else System.out.println("无对应账号密码\n请再试一次");
                    }
                    thisCard.show();
                    thisCard.ATM();
                    thisCard=null;
                    break;
                case 3:
                    while (thisCard==null){
						System.out.println("请输入账号和密码(输入0退出)");
						account=scanner.next();
						if(account.equals("0")) {
							System.out.println("欢迎下次使用！");
							break;
						}
                        thisCard=findAccount(account,false);
                        if(thisCard==null) System.out.println("账号未注册，请重试");
                        else if (thisCard.checkPassword(scanner.next()))
                            break;
                        else {
							thisCard=null;
							System.out.println("无对应账号密码\n请再试一次");
						}
                    }
                    thisCard.consume(
                            BankMenu.getDigit("请输入消费金额：")
                    );
                    thisCard=null;
                    break;
                case 0:
                    System.out.println("欢迎下次使用");
                    return;
            }
    }
    Card initAccount(){
        String[] choices={"请选择申请的卡的类型：\n1.储蓄卡","2.信用卡","0.返回上一界面"};
        Scanner scanner=new Scanner(System.in);
        String account;
        int choice= BankMenu.selectMenu(choices);
        while (true) {
            System.out.println("请输入账号");
            account=scanner.next();
            if(findAccount(account,true)==null)break;
            else System.out.println("账号已注册");
        }
		return switch (choice) {
			case 1 -> new DepositCard(account);
			case 2 -> new CreditCard(account);
			default -> null;
		};
    }
}
